"""
模型版本 | 业务层
"""

import utils.enum_utils as enum
from components.global_param import get_ctx
from components.logger import log
from components.thread_pool import async_io_task
# from mapping import ModelVersionMapping
from models import (
    # Page,
    # PageQuery,
    # PageSorting,
    POBase,
)
from models.other.ctx import RequestContext
from models.po import ModelVersionPO
from my_typing import *
# from models.request import (
#     VersionDetailRequest,
#     VersionListRequest,
# )
# from models.vo import (
#     ModelVersionDetailVO,
#     ModelVersionListPage,
# )
from service import ModelVersionService
from utils.data_utils.special import ObjectIdStr
from utils.decorator_utils import task_exc_catcher


# from utils.exception_utils import BusinessError


#
# class VersionValidator:
#     """ 模型版本 | 校验器 """
#
#     @classmethod
#     def validate_exist(cls, version_id: ObjectId) -> None:
#         """ 校验模型版本是否存在 """
#
#         if not ModelVersionService.get_one_by_id(version_id):
#             raise BusinessError(f"模型版本 ID <{version_id}> 不存在")
#
#
# class VersionGetter:
#     """ 模型版本 | 获取器 """
#
#     @staticmethod
#     def get_detail(request: VersionDetailRequest) -> ModelVersionDetailVO:
#         """ 获取模型版本详情 """
#
#         VersionValidator.validate_exist(request.log_oid)
#         file_po: ModelVersionPO = ModelVersionService.get_one_by_id(request.log_oid)
#
#         return ModelVersionMapping.po_2_detail_vo(file_po)
#
#     @staticmethod
#     def get_list_page_query(request: VersionListRequest) -> PageQuery:
#         """ 获取模型版本列表分页查询 """
#
#         sorting: list[PageSorting] = []
#
#         if request.sort_by_request_time is not None:
#             sorting.append(PageSorting(field="time_info.in_time", order=request.sort_by_request_time))
#
#         if request.sort_by_method is not None:
#             sorting.append(PageSorting(field="route_info.method", order=request.sort_by_method))
#
#         if request.sort_by_user_id is not None:
#             sorting.append(PageSorting(field="user_id", order=request.sort_by_user_id))
#
#         query: dict = {}
#
#         if request.request_time_start is not None:
#             query.setdefault("time_info.in_time", {}).update({"$gte": request.request_time_start})
#
#         if request.request_time_end is not None:
#             query.setdefault("time_info.in_time", {}).update({"$lte": request.request_time_end})
#
#         if request.request_id is not None:
#             query["request_id"] = request.request_id
#
#         if request.user_id is not None:
#             query["user_id"] = request.user_oid
#
#         if request.path is not None:
#             query["route_info.path"] = {"$regex": request.path}
#
#         if request.method is not None:
#             query["route_info.method"] = request.method
#
#         if request.use_time_min is not None:
#             query.setdefault("time_info.total_seconds", {}).update({"$gte": request.use_time_min})
#
#         if request.use_time_max is not None:
#             query.setdefault("time_info.total_seconds", {}).update({"$lte": request.use_time_max})
#
#         return PageQuery(
#             page=request.page,
#             page_size=request.page_size,
#             sorting=sorting,
#             query=query,
#         )
#
#     @classmethod
#     def get_list(cls, request: VersionListRequest) -> ModelVersionListPage:
#         """ 获取模型版本列表 """
#
#         page_query: PageQuery = cls.get_list_page_query(request)
#         request_log_po_page: Page = ModelVersionService.paginated_query(page_query)
#
#         return ModelVersionMapping.po_page_2_vo_page(request_log_po_page)
#

class VersionSetter:
    """ 模型版本 | 设置器 """

    @staticmethod
    def _is_po_changed(
        old_po: POBase | None = None,
        new_po: POBase | None = None,
    ) -> bool:
        """ 判断 PO 属性是否变更（排除基础字段 id、is_deleted、create_time、update_time） """

        if not (
            old_po
            and new_po
        ):
            return False

        old_po_dic: dict = old_po.model_dump(exclude=POBase.base_fields())
        new_po_dic: dict = new_po.model_dump(exclude=POBase.base_fields())

        return old_po_dic != new_po_dic

    @classmethod
    def make_model_version_po(
        cls,
        old_po: POBase | None = None,
        new_po: POBase | None = None,
        *,
        model_operation: enum.ModelOperation,
        po_operation: enum.POOperation,
        rollback_id: ObjectIdStr | None = None,
        rollback_desc: str = "",
        user_id: ObjectIdStr | None = None,
    ) -> ModelVersionPO:
        """
        组装模型版本 PO

        Args:
            old_po: 旧的 PO 对象
            new_po: 新的 PO 对象
            model_operation: 模型操作类型
            po_operation: PO 操作类型
            rollback_id: 回滚 ID（Version ID）
            rollback_desc: 回滚描述
            user_id: 用户 ID

        Returns:
            模型版本 PO 对象
        """

        ctx: RequestContext = get_ctx()
        valid_po: POBase = old_po or new_po
        request_id: StrOrNone = ctx.request_id
        _user_id: ObjectIdStr | None = user_id or ctx.user_id
        changed: bool = cls._is_po_changed(old_po, new_po)
        po_desc: str = valid_po.__doc__.strip()
        po_id: ObjectIdStr = valid_po.id
        new_data = old_data = {}

        if new_po:
            new_data = new_po.to_db_dict()

        if old_po:
            old_data = old_po.to_db_dict()

        return ModelVersionPO(
            changed=changed,
            model_operation=model_operation,
            new_data=new_data,
            old_data=old_data,
            po_id=po_id,
            po_desc=po_desc,
            po_operation=po_operation,
            request_id=request_id,
            rollback_id=rollback_id,
            rollback_desc=rollback_desc,
            user_id=_user_id,
        )

    @staticmethod
    @async_io_task
    @task_exc_catcher(logger=log)
    def async_create_model_version(model_version_po: ModelVersionPO) -> None:
        """ 创建 | 单条 | 模型版本 """

        ModelVersionService.insert_one(model_version_po)

    @classmethod
    def async_create_version(
        cls,
        old_po: POBase | None = None,
        new_po: POBase | None = None,
        *,
        model_operation: enum.ModelOperation,
        po_operation: enum.POOperation,
        rollback_id: ObjectIdStr | None = None,
        rollback_desc: str = "",
        user_id: ObjectIdStr | None = None,
    ) -> None:
        """
        异步创建模型版本

        Args:
            old_po: 旧的 PO 对象
            new_po: 新的 PO 对象
            model_operation: 模型操作类型
            po_operation: PO 操作类型
            rollback_id: 回滚 ID（Version ID）
            rollback_desc: 回滚描述
            user_id: 用户 ID
        """

        model_version_po: ModelVersionPO = cls.make_model_version_po(
            old_po=old_po,
            new_po=new_po,
            model_operation=model_operation,
            po_operation=po_operation,
            rollback_id=rollback_id,
            rollback_desc=rollback_desc,
            user_id=user_id,
        )
        cls.async_create_model_version(model_version_po)
